package soundscovery;

import ecologylab.xml.ElementState;
import ecologylab.xml.TranslationSpace;
import jAudioFeatureExtractor.Controller;
import jAudioFeatureExtractor.DataModel;
import jAudioFeatureExtractor.ModelListener;
import jAudioFeatureExtractor.ACE.DataTypes.Batch;
import jAudioFeatureExtractor.ACE.DataTypes.FeatureDefinition;
import jAudioFeatureExtractor.Aggregators.Aggregator;
import jAudioFeatureExtractor.Aggregators.AggregatorContainer;
import jAudioFeatureExtractor.AudioFeatures.FeatureExtractor;
import jAudioFeatureExtractor.DataTypes.RecordingInfo;
import javax.sound.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;
import kohonen.LearningData;
import kohonen.WTALearningFunction;
import metrics.EuclidesMetric;
import network.DefaultNetwork;
import topology.MatrixTopology;
import java.util.Vector;
import javax.swing.JFileChooser;
import javax.sound.*;
import learningFactorFunctional.GaussFunctionalFactor;
import metrics.MinkowskiMetric;
import org.w3c.dom.NodeList;

public class Launch {
public static String folderOfWavFiles="";
static AllSounds allSounds;
static Vector<Vector<Sound>> clusters=new Stack<Vector<Sound>>();
static int mfccIndex=0;

static int width = 20;
static int height = 20;
static int runs = 4000;
static int mfccCount = 5;
static int lpcCount = 5;

static String workingDirectory="";
static AePlayWav player;
public static void playSound(String nameWithoutWavExtension)
{
    System.out.println("Playing "+folderOfWavFiles+nameWithoutWavExtension+".wav");
//    if(player != null){
//    	player.stopPlaying();
    //}
    player = new AePlayWav(folderOfWavFiles+nameWithoutWavExtension+".wav");//.start();
    player.start();
}

//addSave Vector of sound files to folder
public static void saveSounds(Vector<String> toSaveNoExtensions)
{
	String folderToSaveTo="";
    System.out.println("Trying to choose a folder");
    JFileChooser chooser = new JFileChooser();
    chooser.setCurrentDirectory(new java.io.File("."));
    chooser.setDialogTitle("Select a Folder with Wav Files");
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    //
    // disable the "All files" option.
    //
    chooser.setAcceptAllFileFilterUsed(false);
    //
    if (chooser.showOpenDialog(null) == JFileChooser.OPEN_DIALOG) {
      System.out.println("getCurrentDirectory(): "
         +  chooser.getCurrentDirectory());
      System.out.println("getSelectedFile() : "
         +  chooser.getSelectedFile());
      folderToSaveTo=chooser.getSelectedFile().toString()+"\\";
      }
    else {
      System.out.println("No Selection ");
      }
    
    for(int i=0; i<toSaveNoExtensions.size();i++)
    {
    	String fromfile = folderOfWavFiles+toSaveNoExtensions.get(i)+".wav";
    	String tofile = folderToSaveTo+toSaveNoExtensions.get(i)+".wav";
    	System.out.println("Copying\n"+fromfile+"\n to \n"+tofile);
    	CopyFile.copyfile(fromfile, tofile);
    }
}

public static void chooseFolder()
{
    System.out.println("Trying to choose a folder");
    JFileChooser chooser = new JFileChooser();
    chooser.setCurrentDirectory(new java.io.File("."));
    chooser.setDialogTitle("Select a Folder with Wav Files");
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    //
    // disable the "All files" option.
    //
    chooser.setAcceptAllFileFilterUsed(false);
    //
    if (chooser.showOpenDialog(null) == JFileChooser.OPEN_DIALOG) {
      System.out.println("getCurrentDirectory(): "
         +  chooser.getCurrentDirectory());
      System.out.println("getSelectedFile() : "
         +  chooser.getSelectedFile());
      folderOfWavFiles=chooser.getSelectedFile().toString()+"\\";
      }
    else {
      System.out.println("No Selection ");
      }
}

    public static void executeCommand(String[] files) {
        
        try {
            Runtime rt = Runtime.getRuntime();
            String[] argsp1 = {"cmd.exe", "/E:1900", "/C", "java", "-jar", "jAudio.jar", "-s", "settings.xml", "output.xml"};
            String args[] = new String [argsp1.length+files.length];
            for(int i=0;i<argsp1.length;i++)
            {
                args[i] = argsp1[i];
            }
            for(int i=0;i<files.length;i++)
            {
                args[i+argsp1.length] = folderOfWavFiles+files[i];
//                System.out.println("Argument: "+folderOfWavFiles+files[i]);
            }

            Process proc = rt.exec(args);
            InputStream stdin = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(stdin);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
 //           System.out.println("<OUTPUT>");


            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
//            System.out.println("</OUTPUT>");
            int exitVal = proc.waitFor();
//            System.out.println("Process exitValue: " + exitVal);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public static void pwd() {
        //MFCC cool = new MFCC();
        java.io.File f = new java.io.File(".");
        try {
        	workingDirectory = f.getCanonicalPath();
            System.out.println("PWD: " + workingDirectory);
            
        } catch (Exception e) {
        }
    }

    public static void tryJAudioStuff3()
    {
    	jAudioFeatureExtractor.DataModel d = new DataModel(workingDirectory +"\\features.xml", null);
    	
    	RecordingInfo[] reinfo= new RecordingInfo[listOfFiles.length];
    	
    	String[] aggNames = {"Standard Deviation", "Mean" };
        String[][] aggFeatures = {{}, {}};
        String[][] aggParameters = {{}, {}};
        
       AggregatorContainer ss = new AggregatorContainer();
       
       Batch b=new Batch();
       b.setAggregators(aggNames, aggFeatures, aggParameters);
       try {
		d.aggregators = b.getAggregator();
	} catch (Exception e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
       
       //ss.add(aggNames);
        
    //    d.setAggregators(aggNames,aggFeatures,aggParameters);
    	
    	for(int i=0; i<reinfo.length;i++)
    	{
    		reinfo[i] = new RecordingInfo(folderOfWavFiles+listOfFiles[i]);
    	}
		/////d.recordingInfo = reinfo;
		/*
         * 	
         * <windowSize>512</windowSize>
	<windowOverlap>0.0</windowOverlap>
	<samplingRate>16000.0</samplingRate>
	<normalise>false</normalise>
	<perWindowStats>false</perWindowStats>
	<overallStats>true</overallStats>
	<outputType>ACE</outputType>
	 */
		try {
			d.extract(512, 0, 16000, false, false, true, reinfo, 0);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//ACE is a 0

		System.out.println("Third try section");
		
    	
    }
    public static void tryJAudioStuff2()
    {
    	 Batch b = new Batch();
         
         // Pull input, create the list of files to populate Batch object with
         String[] fileLists = allSounds.getSoundStrings();//(String[])//cc.getDataComponentFromInput(DATA_INPUT_1);
         RecordingInfo[] recording_info = new RecordingInfo[fileLists.length];
         /*File[] names = new File[fileLists.length];
         for (int i = 0; i < names.length; i++) {        	 
                 names[i] = new File(folderOfWavFiles+fileLists[i]);
                 System.out.println("file is "+folderOfWavFiles+fileLists[i]);
         }
         // Go through the files one by one
         for (int i = 0; i < names.length; i++) {
                 // Assume file is invalid as first guess
                 recording_info[i] = new RecordingInfo(names[i].getName(), names[i]
                                                                                 .getPath(), null, false);
         }// for i in names
*///this part is not needed because of listOfFiles
         // Get location of features.xml for building the datamodel and
         // initializing features on/off and attributes hashmaps;
         String fFile = workingDirectory+"\\features.xml";//String.valueOf(cc.getProperty(DATA_PROPERTY_FFILE));
         //ModelListener mm = new ;
		 DataModel dm = new DataModel(fFile,null);//new Controller() );
         FeatureDefinition[] definitions = dm.featureDefinitions;
         FeatureExtractor[] fe = dm.features;
         String[] feAttributes = new String[] {};
         HashMap<String, Boolean> active = new HashMap<String, Boolean>();
         HashMap<String, String[]> attribute = new HashMap<String, String[]>();
         // populate the hashmap with a default of everything off

         for (int i = 0; i < dm.defaults.length; i++) {
                 Boolean defa = new Boolean(false);
                 active.put(definitions[i].name, defa);
                 feAttributes = fe[i].getFeatureDefinition().attributes;
                 if (feAttributes.length > 0) {
                         String[] feAttributeValues = new String[feAttributes.length];
                         for (int j = 0; j < feAttributes.length; j++) {
                                 try {
                                         feAttributeValues[j] = fe[i].getElement(j);
                                 } catch(Exception e){
                                         System.out.println("ERROR retrieving attribute value " +
                                                         " for " + definitions[i].name);
                                         feAttributeValues[j] = "";
                                 }
                         }
                         attribute.put(definitions[i].name, feAttributeValues);
                 } else{
                         String[] feAttributeValues = new String[] {};
                         attribute.put(definitions[i].name, feAttributeValues);
                 }
         }

         //rhema, i don't think this matters
         /*

         // Retrieve Analysis Parameters
         sampleRate = Double.valueOf(cc.getProperty(DATA_PROPERTY_SR));
         windowLength = Integer.valueOf(cc.getProperty(DATA_PROPERTY_WL));
         windowOverlap = Double.valueOf(cc.getProperty(DATA_PROPERTY_WOL));
         normalize = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_N));

         // Retrieve Save Settings Parameters
         saveWindow = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_SW));
         saveOverall = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_SO));
         outputType = Integer.valueOf(cc.getProperty(DATA_PROPERTY_OT));
         fvFile = String.valueOf(cc.getProperty(DATA_PROPERTY_FVFILE));
         fdFile = String.valueOf(cc.getProperty(DATA_PROPERTY_FDFILE));         
         
         String fid = processResultsDir ;
*/         
 
/*         
 File outDir = new File(fid);
 if (!outDir.exists())
 {
     boolean done = outDir.mkdirs();
     if (!done){
         throw new RuntimeException("Could not create the output directory");
     }
 }else if (!outDir.isDirectory()){
     throw new RuntimeException(outDir + " No such Parent directory");
 }
 */
         
         String fdout = "output.xmlFD.xml";//fid + File.separator + fdFile;
         String fvout = "output.xmlFV.xml";//fid + File.separator + fvFile;

    //     cout.println("\nThe results will be in http://nema.lis.uiuc.edu:1814/public/resources/"+fid.substring(22)+fvFile);
         
         //rhema, not resued??
         /*
         // Retrieve Feature Extraction Attribute Settings/Parameters
         // centroid and set in the hashmaps
         
         centroid = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_CENTROID));
         active.put(DATA_PROPERTY_CENTROID, new Boolean(centroid));
         //rolloff
         rolloff = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_ROLLOFF));
         active.put(DATA_PROPERTY_ROLLOFF, new Boolean(rolloff));
         rolloffVal = String.valueOf(cc.getProperty(DATA_PROPERTY_ROLLOFFV));
         attribute.put(DATA_PROPERTY_ROLLOFF, new String[] {rolloffVal});
         //flux
         flux = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_FLUX));
         active.put(DATA_PROPERTY_FLUX, new Boolean(flux));
         //compactness
         compactness = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_COMPACTNESS));
         active.put(DATA_PROPERTY_COMPACTNESS, new Boolean(compactness));
         // Spectral Variability
         variability = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_VARIABILITY));
         active.put(DATA_PROPERTY_VARIABILITY, new Boolean(variability));
         // Root Mean Square
         rms = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_RMS));
         active.put(DATA_PROPERTY_RMS, new Boolean(rms));
         // Fraction Of Low Energy Windows
         fraction = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_FRACTION));
         active.put(DATA_PROPERTY_FRACTION, new Boolean(fraction));
         //Zero Crossings
         zcr = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_ZCR));
         active.put(DATA_PROPERTY_ZCR, new Boolean(zcr));
         // MFCC
         mfcc = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_MFCC));
         active.put(DATA_PROPERTY_MFCC, new Boolean(mfcc));
         mfccVal = String.valueOf(cc.getProperty(DATA_PROPERTY_MFCCV));
         attribute.put(DATA_PROPERTY_MFCC, new String[] {mfccVal});
         mfccd = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_MFCCD));
         active.put(DATA_PROPERTY_MFCCD, new Boolean(mfccd));
         attribute.put(DATA_PROPERTY_MFCCD, new String[] {mfccVal});
         // Moments
         moments = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_MOMENTS));
         active.put(DATA_PROPERTY_MOMENTS, new Boolean(moments));
         // Strongest Beat
         sb = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_SB));
         active.put(DATA_PROPERTY_SB, new Boolean(sb));
         ssb = Boolean.valueOf(cc.getProperty(DATA_PROPERTY_SSB));
         active.put(DATA_PROPERTY_SSB, new Boolean(ssb));
         */

         // Set AGGREGATORS
         String[] aggNames = {"Standard Deviation", "Mean" };
         String[][] aggFeatures = {{}, {}};
         String[][] aggParameters = {{}, {}};
         OutputStream destinationFK = null;
         OutputStream destinationFV = null;
         try {
                 destinationFK = new FileOutputStream(new File(fdout));
                 destinationFV = new FileOutputStream(new File(fvout));
         } catch(Exception e) {}
         System.out.println("Adding Extraction Options and Parameters to jAudio Feature Extraction Batch");
         dm.featureKey = destinationFK;
         dm.featureValue = destinationFV;
         
         /*
          * 	
          * <windowSize>512</windowSize>
	<windowOverlap>0.0</windowOverlap>
	<samplingRate>16000.0</samplingRate>
	<normalise>false</normalise>
	<perWindowStats>false</perWindowStats>
	<overallStats>true</overallStats>
	<outputType>ACE</outputType>
	 */
         
         active.put("MFCC", true);
         attribute.put("MFCC", new String[]{""+mfccCount});
         active.put("LPC", true);
         attribute.put("LPC", new String[]{"0",""+lpcCount});         
         
	 b.setDataModel(dm);        	 
         b.setWindowSize(512);
         b.setWindowOverlap(0);
         b.setSamplingRate(16000);
         b.setNormalise(false);
         b.setPerWindow(false);
         b.setOverall(true);
  //       b.setRecording(recording_info);
         try {
			b.setRecordings(listOfFiles);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		 b.setOutputType(0);//ACE is a 0
         b.setFeatures(active,attribute);
         b.setAggregators(aggNames,aggFeatures,aggParameters);
         
         
          
         try {
			b.execute();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
         /*oldblock
         b.setDataModel(dm);        
         b.setWindowSize(windowLength);
         b.setWindowOverlap(windowOverlap);
         b.setSamplingRate(sampleRate);
         b.setNormalise(normalize);
         b.setPerWindow(saveWindow);
         b.setOverall(saveOverall);
         b.setRecording(recording_info);
         b.setOutputType(outputType);
         b.setFeatures(active,attribute);
         b.setAggregators(aggNames,aggFeatures,aggParameters);
         */
         // OUTPUT
         System.out.println("Outputting jAudio Batch job for execution");
         //cout.flush();
        // cc.pushDataComponentToOutput(DATA_OUTPUT_1, b);

    }
    
    public static void tryJAudioStuff()
    {
    	Batch b = new Batch();
    	HashMap<String, Boolean> activated = new HashMap<String, Boolean>();
    	activated.put("MFCC Overall Average", true);
		HashMap<String, String[]> attributes = new HashMap<String, String[]>();
		attributes.put("MFCC Overall Average", new String[]{"5","100"});
		b.setDestination("output.xmlFK.xml", "output.xmlFV.xml");
				
		DataModel dm = new DataModel("features.xml", null );
		b.setDataModel(dm);
		String[] aggNames = {"Standard Deviation","Mean"};
		String[][] aggFeatures =  new String[0][0];
		String[][] aggParam = new String[0][0];
		b.setAggregators(aggNames, aggFeatures, aggParam);
		
		try {
			b.setRecordings(listOfFiles);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		b.setFeatures(activated, attributes);
		
		
		
		try {
			b.execute();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	
    }
    
    public static void readXMLOutput() {

        try {
            //ecologylab.xml.XMLTools.getDocumentBuilder().parse(new File("output.xmlFV.xml"));
            Feature_vector_file fvf = (Feature_vector_file) ElementState.translateFromXML(
                    "output.xmlFV.xml",
                    TranslationSpace.get("feature_vector_file_scope", new Class[]{Feature_vector_file.class, DataSet.class, Feature.class, V.class,DataSetId.class}));
//            System.out.println(fvf.comments);
            /*old
             
            for (int i = 0; i < fvf.data_sets.size(); i++) {
//                System.out.println(fvf.data_sets.get(i).data_set_id);
                for (int f = 0; f < fvf.data_sets.get(i).features.size(); f++) {
//                    System.out.println(fvf.data_sets.get(i).features.get(f).name);
                    //MFCC Overall Standard Deviation

//LPC Overall Average
                    if(( "MFCC Overall Average".equals(fvf.data_sets.get(i).features.get(f).name)))
                    {
                        Vector<Double> nums = new Vector<Double>();
                    for (int v = 0; v < fvf.data_sets.get(i).features.get(f).vs.size(); v++) {
                        double n = Double.parseDouble(fvf.data_sets.get(i).features.get(f).vs.get(v));
//                        System.out.println(n);
                        nums.add(n);
                    }
                        allSounds.sounds.elementAt(mfccIndex).setMFCCs(nums);
                        mfccIndex++;
                    }


                }
            }

             */

            for (int i = 0; i < fvf.data_sets.size(); i++) {
//                System.out.println(fvf.data_sets.get(i).data_set_id);
            	Vector<Double> nums = new Vector<Double>();
                for (int f = 0; f < fvf.data_sets.get(i).features.size(); f++) {
//                    System.out.println(fvf.data_sets.get(i).features.get(f).name);
                    //MFCC Overall Standard Deviation

//LPC Overall Average
                	
                    if(( "MFCC Overall Average".equals(fvf.data_sets.get(i).features.get(f).name)))
                    {
                        
                    for (int v = 0; v < fvf.data_sets.get(i).features.get(f).vs.size(); v++) {
                        double n = Double.parseDouble(fvf.data_sets.get(i).features.get(f).vs.get(v));
//                        System.out.println(n);
                        nums.add(n);
                    }
                    
                    }

                    
                    if(( "LPC Overall Average".equals(fvf.data_sets.get(i).features.get(f).name)))
                    {
                        
                    for (int v = 0; v < fvf.data_sets.get(i).features.get(f).vs.size(); v++) {
                        double n = Double.parseDouble(fvf.data_sets.get(i).features.get(f).vs.get(v));
//                        System.out.println(n);
                        nums.add(n);
                    }
                    nums.remove(nums.size()-1);
                    
                    }
                    
                }
                allSounds.sounds.elementAt(mfccIndex).setMFCCs(nums);
                mfccIndex++;
            }
                        
            
        } catch (Exception e) {
            System.out.println("EXCEPTION IS " + e.toString());
            e.printStackTrace();
        }

        System.out.println(mfccIndex+"done");
    }
    String[] aSrtings = {"", ""};
    //  jAudioFeatureExtractor.

    public static Double[] toDoubleArray(double[] input) {
        Double[] ret = new Double[input.length];
        for (int i = 0; i < input.length; i++) {
            ret[i] = new Double(input[i]);
        }
        return ret;
    }

    public static void printV(Double[] v) {
        for (int i = 0; i < v.length; i++) {
            System.out.print(v[i] + "  ");
        }
        System.out.println();
    }
     public static void printV(double[] v) {
        for (int i = 0; i < v.length; i++) {
            System.out.print(v[i] + "  ");
        }
        System.out.println();
    }
    static int depth = 0;

    static void printAllNodeChildren(NodeList nl, String trace) {
        depth++;

        if (nl.getLength() == 0) {
            return;
        }

        System.out.println("trace:" + trace);//At depth "+depth);
        for (int i = 0; i < nl.getLength(); i++) {
            System.out.println("val " + nl.item(i).getNodeValue() + "  name  " + nl.item(i).getNodeName());
        }
        for (int i = 0; i < nl.getLength(); i++) {
            NodeList k = nl.item(i).getChildNodes();

            printAllNodeChildren(k, trace + "->" + (i));
            depth--;
        }


    }

    static File[] listOfFiles;
    public static String[] findFilesInFolder()
    {
        File folder = new File(folderOfWavFiles);
        listOfFiles = folder.listFiles();
    String[] ret = new String[listOfFiles.length];

    for (int i = 0; i < listOfFiles.length; i++) {
      if (listOfFiles[i].isFile()) {
        System.out.println("File " + listOfFiles[i].getName());
        ret[i]=listOfFiles[i].getName();
      } else if (listOfFiles[i].isDirectory()) {
        System.out.println("Directory " + listOfFiles[i].getName());
      }
    }
    return ret;
  }

    public static void populateAllFeatures()
    {
        mfccIndex=0;
        String[] s = allSounds.getSoundStrings();
        while(s!=null){
         executeCommand(s);
         readXMLOutput();
         s = allSounds.getSoundStrings();
        }
    }


    public static void main(String args[]) {

    	Scanner in = new Scanner(System.in);
    	System.out.println("Width:");
    	width = in.nextInt();
    	System.out.println("Height:");
    	height = in.nextInt();
    	System.out.println("Runs:");
    	runs = in.nextInt();
    	System.out.println("Mfcc Count");
    	mfccCount = in.nextInt();
    	System.out.println("Lpc Count");
    	lpcCount = in.nextInt();    	

    	
    	
        pwd();
        chooseFolder();
        allSounds = new AllSounds(findFilesInFolder());
        //populateAllFeatures();
        tryJAudioStuff2();
        //tryJAudioStuff3();
        readXMLOutput();
        allSounds.print();

        //NORMALIZE HERE

        Vector<double[]> newMfccs = new Vector<double[]>();//(allSounds.getMFCCs().size());
        
        for(int i=0;i<allSounds.getMFCCs().size();i++)
        {        
            newMfccs.add(new double[allSounds.getMFCCs().get(0).length]);
        }

        double weights[] = new double[allSounds.getMFCCs().get(0).length];
        for(int i=0;i<allSounds.getMFCCs().get(0).length;i++)
        {
              weights[i] = 1;
        }
        Normalizer.normalize(allSounds.getMFCCs(), weights, newMfccs);
        allSounds.setMFCCs(newMfccs);
        System.out.println("Normalized Sounds:");
        allSounds.print();


        System.out.println("Training network..");

        trainSOM();
        printClusters(clusters);
        
        UITry3.main(args);
        UITry3.setG(clusters,width,height);//dodododo
        
    }

    private static void printClusters(Vector<Vector<Sound>> clusters) {
        for (int i = 0; i < clusters.size(); i++) {
            if (clusters.elementAt(i).size() > 0) {
                System.out.println("Now printing out the " + clusters.elementAt(i).size() + " items of cluster " + i);
            }
            for (int k = 0; k < clusters.elementAt(i).size(); k++) {
                System.out.print(clusters.elementAt(i).elementAt(k).filename+" ");
                printV(clusters.elementAt(i).get(k).mfccs);
            }
        }
        System.out.println("Cluster Summary:");
        System.out.println("There are "+clusters.size());
        int numNotThere = 0;
        for (int i = 0; i < clusters.size(); i++) {
            if (clusters.elementAt(i).size() > 0) {
            System.out.println(clusters.get(i).size()+"  ");
            }
            else
            {
                numNotThere++;
            }
        }
        System.out.println("There are "+numNotThere+" unpopulated nodes");
    }

    private static void populateClusters(DefaultNetwork network, LearningData fileData) {
        for (int n = 0; n < network.getNumbersOfNeurons(); n++) {
            clusters.add(new Vector<Sound>());
        }
        for (int i = 0; i < fileData.getDataSize(); i++) {
            int classNum = 0;
            double currentDistance = Double.MAX_VALUE;
            double[] dataValue = fileData.getData(i);
            for (int n = 0; n < network.getNumbersOfNeurons(); n++) {
                double[] neuronWeight = network.getNeuron(n).getWeight();                
                EuclidesMetric m = new EuclidesMetric();
                //MinkowskiMetric m = new MinkowskiMetric(5);

                double dist = m.getDistance(neuronWeight, dataValue);
                if (dist < currentDistance) {
                    classNum = n;
                    currentDistance = dist;
                }
            }
            clusters.elementAt(classNum).add(allSounds.sounds.get(i));
        }


    }

    private static DefaultNetwork trainSOM(){//(DefaultNetwork network, LearningData fileData) {

        System.out.println("Loading data..");
        //////LearningData fileData;
        LearningData fileData = new LearningData(allSounds.getMFCCs());
        MatrixTopology topology = new MatrixTopology(width, height);

        double[] maxWeight = new double [(allSounds.getMFCCs().get(0).length)];
        for(int i=0; i<maxWeight.length; i++)
        {
            maxWeight[i] = .001;//.05;
        }
        DefaultNetwork network = new DefaultNetwork(allSounds.getMFCCs().get(0).length, maxWeight, topology);
        //ConstantFunctionalFactor constantFactor = new ConstantFunctionalFactor(1);//.8

        //ExponentionalFunctionFactor constantFactor = new ExponentionalFunctionFactor(9, 29);

        //LinearFunctionalFactor constantFactor = new LinearFunctionalFactor(.5,200);
        GaussFunctionalFactor constantFactor = new GaussFunctionalFactor();
        double[] params = new double[2];
        params[0] = 2;
        constantFactor.setParameters(params);

//formerly used Eucidiean
        WTALearningFunction learning = new WTALearningFunction(network, runs, new EuclidesMetric(), fileData, constantFactor);
        System.out.println("actually learning");
        learning.learn();
        //network.networkToFile("c:/network_after.txt");
        System.out.println(network);
        System.out.println("projecting");
        populateClusters(network, fileData);
        System.out.println("finished learning");
        return network;
    }
}
